package cn.hzu580.bean;

import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import javax.annotation.Resource;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.opensymphony.xwork2.ActionContext;

import cn.hzu580.util.DateUtil;
import cn.hzu580.util.MsgCodeUtil;

/**
 * 短信请求守护线程，防止恶意刷短信
 * @author 沫熊工作室 <a href="http://www.darhao.cc">www.darhao.cc</a>
 */
@Component
public class MsgDaemon {

	private Set<Map<String, Object>> forbiddenSet;
	
	//单位秒
	private static final int TIME_OUT = 60;
	
	
	@Resource
	private CodeDaemon codeDaemon;
	
	
	public MsgDaemon() {
		forbiddenSet = new HashSet<Map<String, Object>>();
	}
	
	
	/**
	 * 周期性维护该Set，把与当前时间超过指定秒的session从Set中移除，防止内存占用过大
	 */
	@Scheduled(cron="* 0/5 * * * ?")
	public void clearSetTask(){
		Date now = DateUtil.now();
		for (Map<String, Object> map : forbiddenSet) {
			Date date = (Date) map.get("date");
			if(((now.getMinutes() - date.getMinutes()) * 60 + now.getSeconds()) - date.getSeconds() >= TIME_OUT){
				forbiddenSet.remove(map);
			}
		}
	}
	
	
	/**
	 *尝试使用该session发送验证短信。
	 *失败返回false；
	 *成功则发送短信，记录短信验证码到session，并返回成功与否的结果。
	 *该方法具有防刷功能。
	 * @param pSessionID
	 * @return
	 */
	public boolean trySendMsg(String pSessionID, String sessionKey, String tel){
		for (Map<String, Object> map : forbiddenSet) {
			String sessionID = (String) map.get("sessionID");
			//找到该session
			if(sessionID.equals(pSessionID)){
				Date now = DateUtil.now();
				Date date = (Date) map.get("date");
				//如果发送时间间隔小于一分钟则返回false
				if(((now.getMinutes() - date.getMinutes()) * 60 + now.getSeconds()) - date.getSeconds() <= TIME_OUT){
					return false;
				}else{
					map.put("date", DateUtil.now());
					return sendMsg(sessionKey, tel);
				}
			}
		}
		//forbiddenSet内无该session则添加该session，并返回true
		HashMap<String, Object> m = new HashMap<String, Object>();
		m.put("sessionID", pSessionID);
		m.put("date", DateUtil.now());
		forbiddenSet.add(m);
		return sendMsg(sessionKey, tel);
	}
	
	
	private boolean sendMsg(String sessionKey, String tel){
		Random random = new Random();
		String code = "";
		for (int i = 0;  i < 4; i++) {
			code = code + Math.abs((random.nextInt() % 10));
		}
		if(MsgCodeUtil.sendValidateMsg(code, tel)){
			ActionContext.getContext().getSession().put(sessionKey, code);
			codeDaemon.time(sessionKey);
			return true;
		}else{
			return false;
		}
		
	}
	
	public CodeDaemon getCodeDaemon() {
		return codeDaemon;
	}

	public void setCodeDaemon(CodeDaemon codeDaemon) {
		this.codeDaemon = codeDaemon;
	}
	
}
